package com.dodayum;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.google.common.base.Throwables;

import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Call {

    /**
     * TODO 待优化：
     *  单例模式，目前代码太臃肿了
     *  一次只能加载一个jar包（考虑本地缓存）
     */

    private final String loadClass; // 调用的借口类
    private final String method; // 调用的方法名
    private final Object input; // 调用的参数

    /**
     * 初始化链接
     * @param loadClass 要调用的借口
     * @param method 要调用的方法
     * @param input 请求参数
     */
    public Call(String loadClass, String method, Object input) {
        this.loadClass = loadClass;
        this.method = method;
        this.input = input;
    }

    public Object call() {
        // TODO 这里目前只支持一个jar包，需要批量搞一下
        String interfacePath = "/Users/dodayum/Desktop/user-service-interface-1.0-SNAPSHOT.jar";
        // 获取文件
        URL url1;
        try {
            url1 = new URL("file:" + interfacePath);
        } catch (MalformedURLException e) {
            System.out.println(Throwables.getStackTraceAsString(e));
            return String.format("jar包获取失败，请检查jar包的位置是否存在:%s", interfacePath);
        }
        //获取类加载器
        URLClassLoader myClassLoader1 = new URLClassLoader(new URL[]{url1}, Thread.currentThread().getContextClassLoader());
        //获取对应的类

        SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");

        System.out.println("begin\t" + timeFormatter.format(new Date(System.currentTimeMillis())));
        Object response = this.demoCall(myClassLoader1);
        System.out.println("over\t" + timeFormatter.format(new Date(System.currentTimeMillis())));
        return response;

    }

    private Object demoCall(URLClassLoader myClassLoader1) {
        // 从jar包中解析出来类
        Class<?> interfaceClass;
        try {
            interfaceClass = myClassLoader1.loadClass(this.loadClass);
        } catch (ClassNotFoundException e) {
            System.out.println(Throwables.getStackTraceAsString(e));
            return String.format("调用失败，请检查jar包里是否有这个类:%s", this.loadClass);
        }

        // 当前应用设置
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("api-demo-consumer");

        // 注册中心设置
        RegistryConfig registryConfig = new RegistryConfig("zookeeper://192.168.252.128:2181");

        // 代理
        ReferenceConfig<Object> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setApplication(applicationConfig);
        referenceConfig.setRegistry(registryConfig);
        referenceConfig.setInterface(interfaceClass);
//        referenceConfig.setUrl("dubbo://127.0.0.1:12345/"+interfaceClass.getName());

        // 开始连接
        Object reference = referenceConfig.get();

        // 调用里面的方法
        Method method;

        try {
            Class<?> aClass = reference.getClass();
            method = aClass.getMethod(this.method, this.input.getClass());
        } catch (NoSuchMethodException e) {
            System.out.println(Throwables.getStackTraceAsString(e));
            return String.format("调用失败，请检查%s里是否有这个方法:%s", this.loadClass, this.method);
        }

        try {
            return method.invoke(reference, this.input);
        } catch (Exception e) {
            System.out.println(Throwables.getStackTraceAsString(e));
            return String.format("反射调用失败，请查看日志，原因：%s", e);
        }
    }

}
